//
//  KooCalendarView.h
//  KooIEDUCalendarDemo
//
//  Created by nowcoder on 2024.
//

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@class KooCalendarView, KooCalendarModel, KooCalendarConfig;

// MARK: - KooCalendarViewDelegate Protocol
@protocol KooCalendarViewDelegate <NSObject>

@optional
/**
 * 日期选中状态发生变化时的回调
 * @param calendarView 日历视图
 * @param selectedDates 当前所有选中的日期数组
 * @param changedDate 发生变化的日期
 * @param isSelected 该日期是否被选中（YES为选中，NO为取消选中）
 */
- (void)calendarView:(KooCalendarView *)calendarView 
       selectedDates:(NSArray<NSDate *> *)selectedDates
         changedDate:(NSDate *)changedDate 
          isSelected:(BOOL)isSelected;

/**
 * 达到最大选择数量限制时的回调
 * @param calendarView 日历视图
 * @param maxCount 最大可选择数量
 */
- (void)calendarView:(KooCalendarView *)calendarView 
reachedMaxSelectCount:(NSInteger)maxCount;

/**
 * 月份切换时的回调
 * @param calendarView 日历视图
 * @param currentDate 当前显示月份的日期
 */
- (void)calendarView:(KooCalendarView *)calendarView 
    monthChangedTo:(NSDate *)currentDate;

@end

// MARK: - KooCalendarDataSource Protocol
@protocol KooCalendarDataSource <NSObject>

@optional
/**
 * 自定义日期单元格的显示内容
 * @param calendarView 日历视图
 * @param date 日期
 * @return 返回自定义的显示文本，返回nil使用默认显示
 */
- (NSString * _Nullable)calendarView:(KooCalendarView *)calendarView 
                    displayTextForDate:(NSDate *)date;

/**
 * 判断指定日期是否可选择
 * @param calendarView 日历视图
 * @param date 日期
 * @return YES表示可选择，NO表示不可选择
 */
- (BOOL)calendarView:(KooCalendarView *)calendarView 
     shouldSelectDate:(NSDate *)date;

@end

// MARK: - KooCalendarView Interface
@interface KooCalendarView : UIView

// MARK: - Properties
/** 代理对象 */
@property (nonatomic, weak) id<KooCalendarViewDelegate> delegate;

/** 数据源对象 */
@property (nonatomic, weak) id<KooCalendarDataSource> dataSource;

/** 配置对象 */
@property (nonatomic, strong) KooCalendarConfig *config;

/** 当前显示的月份日期 */
@property (nonatomic, strong) NSDate *currentDate;

/** 当前选中的日期数组 */
@property (nonatomic, strong, readonly) NSArray<NSDate *> *selectedDates;

// MARK: - Initialization
/**
 * 使用默认配置初始化日历视图
 */
- (instancetype)init;

/**
 * 使用自定义配置初始化日历视图
 * @param config 配置对象
 */
- (instancetype)initWithConfig:(KooCalendarConfig *)config;

/**
 * 使用预设选中日期初始化日历视图
 * @param preSelectedDates 预设选中的日期数组
 */
- (instancetype)initWithPreSelectedDates:(NSArray<NSDate *> *)preSelectedDates;

/**
 * 使用配置和预设选中日期初始化日历视图
 * @param config 配置对象
 * @param preSelectedDates 预设选中的日期数组
 */
- (instancetype)initWithConfig:(KooCalendarConfig *)config 
                preSelectedDates:(NSArray<NSDate *> *)preSelectedDates;

// MARK: - Public Methods
/**
 * 刷新日历视图
 */
- (void)reloadCalendar;

/**
 * 切换到指定月份
 * @param date 目标月份的任意日期
 */
- (void)switchToMonth:(NSDate *)date;

/**
 * 选中指定日期
 * @param date 要选中的日期
 * @return YES表示选中成功，NO表示选中失败
 */
- (BOOL)selectDate:(NSDate *)date;

/**
 * 取消选中指定日期
 * @param date 要取消选中的日期
 */
- (void)deselectDate:(NSDate *)date;

/**
 * 清空所有选中的日期
 */
- (void)clearSelectedDates;

/**
 * 删除最后一个选中的日期
 * @return 被删除的日期，如果没有选中日期则返回nil
 */
- (NSDate * _Nullable)removeLastSelectedDate;

/**
 * 获取指定日期是否已选中
 * @param date 要查询的日期
 * @return YES表示已选中，NO表示未选中
 */
- (BOOL)isDateSelected:(NSDate *)date;

/**
 * 批量设置选中日期列表并更新UI
 * @param dates 要设置为选中状态的日期数组，传入nil或空数组将清空所有选中日期
 * @param animated 是否使用动画效果更新UI
 */
- (void)setSelectedDates:(NSArray<NSDate *> * _Nullable)dates animated:(BOOL)animated;

@end

NS_ASSUME_NONNULL_END 
